#ifndef _CONSOLE_LOGGER_H_
#define _CONSOLE_LOGGER_H_

#include <iomanip>

#define __TLSUSERNAME__ pthread_self()

inline string _NOW()
{
	struct timeval tv;
	struct tm tm;
	char buf[28] = {0};
	int len = 0;

	gettimeofday(&tv, NULL);
	localtime_r(&tv.tv_sec, &tm);
	len = strftime(buf, sizeof buf, "%Y%m%d %H:%M:%S", &tm);
	sprintf(buf + len, ".%06d", (int)(tv.tv_usec));
	
	return buf;
}

#ifdef TRACE
#define LOG_LOG(level, msg) std::cout << "[" << _NOW() << "] [" << #level << "] [" << __FILE__ << ":" << __LINE__ << "] [" <<__FUNCTION__ << "] [" << __TLSUSERNAME__ << "] " << msg << endl
#define LOG_DEBUG(msg) LOG_LOG(DEBUG, msg)
#define LOG_TRACE(msg) LOG_LOG(TRACE, msg)
#define LOG_WARN(msg) LOG_LOG(WARN, msg)
#define LOG_ERROR(msg) LOG_LOG(ERROR, msg)
#define LOG_BUFFER(hint, buf, len) do {\
	std::ostringstream oss;\
	oss << std::hex << std::setw(2) << std::setfill('0') << std::setiosflags(ios::uppercase);\
	for (unsigned int i = 0; i < (unsigned int)len; i++) {\
		oss << std::setw(2) << (int)(unsigned char)(*(buf + i));\
	} \
	LOG_TRACE(hint << ": " << oss.str());\
} while(0)          
#else
#define LOG_DEBUG(msg)
#define LOG_TRACE(msg)
#define LOG_WARN(msg)
#define LOG_ERROR(msg)
#define LOG_BUFFER(hit, buf, len) do { } while (false);
#endif

#endif
